class PlayerCharacterTag_Data {
	Billboard = null;
	InstanceScale = Vector(1, 1, 1);
}

class PlayerCharacterTag {
	static DataTable = [];

	static Register(player) {
		if (this.DataTable[player.ID] == null) {
			this.DataTable[player.ID] = new PlayerCharacterTag_Data();
		}
	}

	static Unregister(player) {
		//可能由于玩家OnPlayerJoin时断线，没有执行到OnPlayerComplete，因此没有Register成功
		if (this.DataTable.indexOf(player.ID) == -1) {
			return;
		}

		this.RemoveBillboard(player);

		if (this.DataTable[player.ID] != null) {
			this.DataTable[player.ID] = null;
		}
	}

	static UpdateAll() {
		let playerCount = World.Player.GetCount();
		for (let i = 0; i < playerCount; i++) {
			this.Update(World.Player.Get(i));
		}
	}

	static Update(player) {
		//Action
		if (player.Entity != null) {
			this.CreateBillboard(player);
		}
		else {
			this.RemoveBillboard(player);
		}
	}

	static CreateBillboard(player) {
		//Check
		//if (this.DataTable[player.ID].Billboard != null && this.DataTable[player.ID].Billboard.Target == player.Entity) return;

		//Old
		this.RemoveBillboard(player);

		//New
		if (player.Entity != null) {
			let billboard = World.Billboard.Create(1, player.Entity.Pos);
			billboard.Baffle = true;
			billboard.Text = `[color=${Misc.ColorToHEX(player.Color)}]${player.Name}[/color]`;
			billboard.Target = player.Entity;
			billboard.Color = Color(0, 0, 0, 100);

			//Ignore
			let cMatch = "-1|";
			let playerCount = World.Player.GetCount();
			for (let i = 0; i < playerCount; i++) {
				let plrID = World.Player.Get(i).ID;
				if (plrID != player.ID) {
					cMatch += `${plrID}|`;
				}
			}
			billboard.Match = cMatch;

			this.DataTable[player.ID].Billboard = billboard;
			this.DataTable[player.ID].InstanceScale = player.Entity.Scale;

			this.UpdateBillboard(player);
		}
	}

	static RemoveBillboard(player) {
		if (this.DataTable[player.ID].Billboard != null) {
			this.DataTable[player.ID].Billboard.Remove();
			this.DataTable[player.ID].Billboard = null;
		}
	}

	static UpdateBillboard(player) {
		if (this.DataTable[player.ID].Billboard != null && player.Entity != null) {
			//Debug.LogError(player.Entity);
			//Debug.LogError(player.Entity.BodyHeight);
			this.DataTable[player.ID].Billboard.Offset = Vector(0, (player.Entity.BodyHeight + 0.2) * this.DataTable[player.ID].InstanceScale.y, 0);
		}
	}
}

World.Core.AddListener("OnScriptLoad", function () {
	Debug.Log("[PlayerCharacterTag] by @bibiboxs");
}, -1);

World.Core.AddListener("OnPlayerComplete", function (player) {
	PlayerCharacterTag.Register(player);
}, -1);

World.Core.AddListener("OnPlayerPart", function (player, reason) {
	PlayerCharacterTag.Unregister(player);
}, -1);

World.Core.AddListener("OnPlayerEntityLogin", function (player, entity) {
	PlayerCharacterTag.UpdateAll();
}, -1);

World.Core.AddListener("OnPlayerEntityLogout", function (player, entity) {
	PlayerCharacterTag.UpdateAll();
}, -1);

World.Core.AddListener("OnPlayerColorChange", function (player, color) {
	PlayerCharacterTag.UpdateAll();
}, -1);

World.Core.AddListener("OnPlayerNameChange", function (player, name) {
	PlayerCharacterTag.UpdateAll();
}, -1);

World.Core.AddListener("OnFrameUpdate", function (dt) {
	let playerCount = World.Player.GetCount();
	for (let i = 0; i < playerCount; i++) {
		let plr = World.Player.Get(i);

		if (PlayerCharacterTag.DataTable[plr.ID] != null) {
			if (plr.Entity && Equals(plr.Entity.Scale, PlayerCharacterTag.DataTable[plr.ID].InstanceScale) == false) {
				PlayerCharacterTag.DataTable[plr.ID].InstanceScale = plr.Entity.Scale;
				PlayerCharacterTag.UpdateBillboard(plr);
			}
		}
	}
}, -1);